package cn.az13js.satool;

import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.Map;

public class Distribution {

    public static void run() {
        printAnalyzeInfo(generateData(100000, 0, 1), -4, 4, 100);
    }

    public static double[] generateData(int total, double average, double standardDeviation) {
        double[] data = new double[total];
        for (int i = 0; i < data.length; i++) {
            data[i] = Util.normalDistribution(average, standardDeviation);
        }
        return data;
    }

    private static class Item {
        public double min;
        public double max;
        public Item(double min, double max) {
            this.min = min;
            this.max = max;
        }
    }

    public static void printAnalyzeInfo(double[] data, double minValue, double maxValue, int distinguish) {
        DecimalFormat formater = new DecimalFormat("0.000000000");
        for (double[] a : getAnalyzeInfo(data, minValue, maxValue, distinguish)) {
            Util.message(formater.format(a[0]) + "," + formater.format(a[1]));
        }
    }

    public static double[][] getAnalyzeInfo(double[] data, double minValue, double maxValue, int distinguish) {
        double d = (maxValue - minValue) / (double)distinguish; // 计算每个间隔的距离
        LinkedHashMap<Item, Integer> summaryInfo = new LinkedHashMap<Item, Integer>(distinguish); // Key是间隔信息（区间），值是对应区间的数据计数（2倍）
        for (int i = 0; i < distinguish; i++) { // 初始化，计数为0
            summaryInfo.put(new Item(minValue + i * d, minValue + (i + 1) * d), 0);
        }
        for (double element : data) { // 遍历数据，计数
            for (Map.Entry<Item, Integer> item : summaryInfo.entrySet()) {
                if (element > item.getKey().min && element <= item.getKey().max) {
                    summaryInfo.put(item.getKey(), item.getValue() + 1);
                }
                if (element >= item.getKey().min && element < item.getKey().max) {
                    summaryInfo.put(item.getKey(), item.getValue() + 1);
                    break;
                }
            }
        }
        double[][] result = Util.nDArray(distinguish, 2);
        int i = 0;
        for (Map.Entry<Item, Integer> item : summaryInfo.entrySet()) {
            result[i][0] = (item.getKey().min + item.getKey().max) / 2;
            result[i][1] = d * item.getValue() / data.length / 2;
            i++;
        }
        return result;
    }
}
